package com.test.game.tiles;

import java.util.HashMap;
import java.util.Map;

import com.test.game.tiles.ports.ClayPortTile;
import com.test.game.tiles.ports.OrePortTile;
import com.test.game.tiles.ports.SheepPortTile;
import com.test.game.tiles.ports.UndefinedPortTile;
import com.test.game.tiles.ports.WheatPortTile;
import com.test.game.tiles.ports.WoodPortTile;
import com.test.game.tiles.resources.ClayTile;
import com.test.game.tiles.resources.OreTile;
import com.test.game.tiles.resources.SheepTile;
import com.test.game.tiles.resources.WheatTile;
import com.test.game.tiles.resources.WoodTile;

public abstract class HexagonalTile {

   public enum Resource { ORE, WHEAT, SHEEP, WOOD, CLAY, UNDEFINED };
   
   public static Map<String, HexagonalTile> hexTypes = new HashMap<String, HexagonalTile>();
   
   private HexagonalTile bottomHex      = null;
   private HexagonalTile bottomRightHex = null;
   private HexagonalTile rightHex       = null;
   private HexagonalTile upRightHex     = null;
   private HexagonalTile upHex          = null;
   private HexagonalTile upLeftHex      = null;
   private HexagonalTile leftHex        = null;
   private HexagonalTile bottomLeftHex  = null;
   
   public abstract HexagonalTile newInstance();
   public abstract HexagonalTile getInstance();
   public abstract void accept(TileVisitor visitor);
   
	public static HexagonalTile createTile(String type) {
	   HexagonalTile newTile = null;
	   if(hexTypes.containsKey(type)) {
	      newTile = hexTypes.get(type).newInstance();
	   }
	   else {
	      System.out.println("Warning!  Invalid Data Map: '" + type + "'.");
	      newTile = new EmptyTile();
	   }
	   
	   return newTile;
	}
	
	/**
	 * <p>Possible values for the map:
    * '   ' = Empty {@link EmptyTile#ABBREVIATION EmptyTile.ABBREVIATION}
    * 'Sea' = Sea
    * 'Und' = Undefined
    * 'Cla' = Clay
    * 'Ore' = Ore
    * 'She' = Sheep
    * 'Whe' = Wheat
    * 'Woo' = Wood
    * 'Des' = Desert
    * 'ClP' = Clay's Port
    * 'ShP' = Sheep's Port
    * 'OrP' = Ore's Port
    * 'WhP' = Wheat's Port
    * 'WoP' = Wood's Port
    * 'UnP' = Undefined resource's Port
    */
	static {
      hexTypes.put(EmptyTile.ABBREVIATION,         EmptyTile.INSTANCE);
      hexTypes.put(SeaTile.ABBREVIATION,           SeaTile.INSTANCE);
      //hexTypes.put(ResourceTile.ABBREVIATION,      ResourceTile.INSTANCE);
      hexTypes.put(ClayTile.ABBREVIATION,          ClayTile.INSTANCE);
      hexTypes.put(OreTile.ABBREVIATION,           OreTile.INSTANCE);
      hexTypes.put(WheatTile.ABBREVIATION,         WheatTile.INSTANCE);
      hexTypes.put(SheepTile.ABBREVIATION,         SheepTile.INSTANCE);
      hexTypes.put(WoodTile.ABBREVIATION,          WoodTile.INSTANCE);
      hexTypes.put(DesertTile.ABBREVIATION,        DesertTile.INSTANCE);
      hexTypes.put(OrePortTile.ABBREVIATION,       OrePortTile.INSTANCE);
      hexTypes.put(WheatPortTile.ABBREVIATION,     WheatPortTile.INSTANCE);
      hexTypes.put(SheepPortTile.ABBREVIATION,     SheepPortTile.INSTANCE);
      hexTypes.put(WoodPortTile.ABBREVIATION,      WoodPortTile.INSTANCE);
      hexTypes.put(ClayPortTile.ABBREVIATION,      ClayPortTile.INSTANCE);
      hexTypes.put(UndefinedPortTile.ABBREVIATION, UndefinedPortTile.INSTANCE);
   }

   public HexagonalTile getBottomHex() {
      return bottomHex;
   }

   public void setBottomHex(HexagonalTile bottomHex) {
      this.bottomHex = bottomHex;
   }

   public HexagonalTile getBottomRightHex() {
      return bottomRightHex;
   }

   public void setBottomRightHex(HexagonalTile bottomRightHex) {
      this.bottomRightHex = bottomRightHex;
   }

   public HexagonalTile getRightHex() {
      return rightHex;
   }

   public void setRightHex(HexagonalTile rightHex) {
      this.rightHex = rightHex;
   }

   public HexagonalTile getUpRightHex() {
      return upRightHex;
   }

   public void setUpRightHex(HexagonalTile upRightHex) {
      this.upRightHex = upRightHex;
   }

   public HexagonalTile getUpHex() {
      return upHex;
   }

   public void setUpHex(HexagonalTile upHex) {
      this.upHex = upHex;
   }

   public HexagonalTile getUpLeftHex() {
      return upLeftHex;
   }

   public void setUpLeftHex(HexagonalTile upLeftHex) {
      this.upLeftHex = upLeftHex;
   }

   public HexagonalTile getLeftHex() {
      return leftHex;
   }

   public void setLeftHex(HexagonalTile leftHex) {
      this.leftHex = leftHex;
   }

   public HexagonalTile getBottomLeftHex() {
      return bottomLeftHex;
   }

   public void setBottomLeftHex(HexagonalTile bottomLeftHex) {
      this.bottomLeftHex = bottomLeftHex;
   }
   
   public boolean isEmptyTile() {
      return false;
   }
}
